package main

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
	"time"
)

var RedisClient *redis.Pool

func main() {

	conn, err := redis.Dial("tcp", "127.0.0.1:6379")
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	w, err := redis.Ints(conn.Do("Mset", "aa", 100, "bb", 200))
	if err != nil {
		//panic(err)
	}
	fmt.Println(w)
	a, _ := redis.Ints(conn.Do("Mget", "aa", "bb"))
	for i := range a {
		fmt.Println(i)
	}
	//set 永不过期
	_, err = conn.Do("Set", "xhc", "xhc hahaha")
	if err != nil {
		//panic(err)
	}
	//十秒过期
	_, err = conn.Do("Set", "xhc1", "xhc hahaha", "EX", 5)
	if err != nil {
		//panic(err)
	}
	//检查key是否存在
	aa, err := redis.Bool(conn.Do("EXISTS", "gwyy"))
	if err != nil {
		//panic(err)
	}
	fmt.Println(aa)
	//删除一个key
	_, err = conn.Do("DEL", "mykey")
	if err != nil {
		fmt.Println("redis delelte failed:", err)
	}
	//list 操作
	_, _ = conn.Do("lpush", "mylist", "redis")
	_, _ = conn.Do("lpush", "mylist", "mongodb")
	_, _ = conn.Do("lpush", "mylist", "mysql")
	//​ value 将一组命令结果转换为 []interface{}。如果err不等于nil，那么Values返回nil，err
	value, _ := redis.Values(conn.Do("lrange", "mylist", "0", "-1"))
	for _, v := range value {
		fmt.Println(string(v.([]byte)))
	}

	r1, err := redis.String(conn.Do("loop", "mylist"))
	if err != nil {
		fmt.Println("get abc failed,", err)
		return
	}
	fmt.Println(r1)

	type Book struct {
		BookName  string
		Author    string
		PageCount string
		Press     string
	}
	top1 := Book{
		BookName:  "Crazy golang",
		Author:    "Moon",
		PageCount: "600",
		Press:     "GoodBook",
	}

	if _, err := conn.Do("HMSET", redis.Args{}.Add("Top1").AddFlat(&top1)...); err != nil {
		fmt.Println(err)
	}
	topx := Book{}
	for _, item := range []string{"Top1"} {
		value, _ := redis.Values(conn.Do("HGETALL", item))
		redis.ScanStruct(value, &topx)
		fmt.Printf("%s[%+v]\n", item, topx)
	}
	stringsValue, _ := redis.Strings(conn.Do("HMGET", "Top1", "BookName", "Author"))
	fmt.Printf("hmget:%+v\n", stringsValue)

	dd := redis.Args{}.Add("aa11").AddFlat("bb")
	conn.Do("Set", dd...)

	args := redis.Args{}
	args = args.Add("gwyy").Add("pipe1").Add("aa11")
	rec1, err1 := redis.ByteSlices(conn.Do("MGET", args...))
	if err1 != nil {
		fmt.Println(rec1)
	}
	/**
	/Do方法组合了Send,Flush和 Receive方法。Do方法先写入命令，然后清空输出buffer，最后接收全部挂起响应包括Do方发出的命令的结果。
	//如果任何响应中包含一个错误，Do返回错误。如果没有错误，Do方法返回最后一个响应。
	*/
	conn.Send("SET", "pipe1", "111")
	conn.Send("GET", "pipe1")
	conn.Send("GET", "xhc")
	conn.Flush()
	conn.Receive()
	v, err := conn.Receive()  //返回了get  pipe1
	v1, err := conn.Receive() //返回了get xhc
	/**
	byte数组转字符串
	*/
	fmt.Println(string(v.([]byte)))
	fmt.Println(string(v1.([]byte)))

	/**
	Redis 池
	*/
	RedisClient = &redis.Pool{
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", "127.0.0.1:6379")
			if err != nil {
				return nil, err
			}
			c.Do("SELECT", 0)
			return c, nil
		},
		//DialContext:     nil,
		//TestOnBorrow:    nil,
		//最大的空闲连接数，表示即使没有redis连接时依然可以保持N个空闲的连接，而不被清除，随时处于待命状态。
		MaxIdle: 1,
		//最大的激活连接数，表示同时最多有N个连接
		MaxActive: 10,
		//最大的空闲连接等待时间，超过此时间后，空闲连接将被关闭
		IdleTimeout: 180 * time.Second,
		//Wait:            false,
		//MaxConnLifetime: 0,
	}
	//拿到一个连接
	conn1 := RedisClient.Get()
	defer conn1.Close()
	r, _ := conn1.Do("GET", "xhc")
	fmt.Println(string(r.([]byte)))

}
